package com.example.springbooteasycode.zjrc.project.OuterMidProd.command11;

import java.util.ArrayList;
import java.util.List;

/**
 * C代码迁移Java实现command11指令：增加节点
 *
 * C代码：trim去空格-》strlen校验长度-》......
 */
public class NodeManager {
    public static void main(String[] args) {
        // 模拟输入节点 ID（十六进制转字符串后的值）
        String nodeID = "NBTC0001";

        // 调用 AddNewNode 逻辑
        int result = NodeManager.addNewNode(nodeID);

        if (result == 0) {
            System.out.println("节点添加成功：" + nodeID);
        } else {
            System.out.println("添加失败，错误码：" + result);
        }

        // 测试添加节点
        System.out.println("添加NBTC0001: " + (addNewNode("NBTC0001") == 0 ? "成功" : "失败"));
        System.out.println("添加NBTC0002: " + (addNewNode("NBTC0002") == 0 ? "成功" : "失败"));
        // 测试添加重复节点
        System.out.println("添加重复的NBTC0001: " + (addNewNode("NBTC0001") == 0 ? "成功" : "失败"));

        // 显示当前节点
        System.out.println("\n当前节点列表:");
        for (PKeyEntry node : mKeyInfo.nKeyArray) {
            System.out.println(node.NodeID);
        }

        // 查看当前节点列表
        System.out.println("当前节点数量：" + mKeyInfo.nKeyAmount);
        for (PKeyEntry node : mKeyInfo.nKeyArray) {
            System.out.println("节点 ID：" + node.NodeID);
        }
    }


    /**
     * 替代 C 的 PKeyEntry 结构体
     */
    static class PKeyEntry {
        String NodeID; // 节点号
        // 可扩展其他字段（如状态、密钥信息等）
    }

    /**
     * 替代 C 的 MKey_Info 全局配置
     */
    static class MKeyInfo {
        // 节点数组（替代 MKey_Array）
        List<PKeyEntry> nKeyArray = new ArrayList<>();
        // 当前节点数量（替代 nKeyAmount）
        int nKeyAmount = 0;
        // 线程安全锁（替代 pthread_mutex）
        final Object lock = new Object();
    }

    private static final MKeyInfo mKeyInfo = new MKeyInfo(); // 全局配置

    /**
     * 替代 C 的 trim 函数：去除首尾空格
     */
    public static String trim(String str) {
        if (str == null) return "";
        return str.trim();
    }

    /**
     * 替代 C 的 GetNode：二分查找节点（判断是否已存在）
     */
    public static PKeyEntry getNode(String szNodeID) {
        List<PKeyEntry> array = mKeyInfo.nKeyArray;
        int low = 0, high = array.size() - 1;

        while (low <= high) {
            int mid = (low + high) / 2;
            PKeyEntry node = array.get(mid);
            int cmp = szNodeID.compareTo(node.NodeID);

            if (cmp == 0) {
                return node; // 找到节点
            } else if (cmp < 0) {
                high = mid - 1;
            } else {
                low = mid + 1;
            }
        }
        return null; // 未找到
    }

    /**
     * 替代 C 的 AddNewNode：完整业务逻辑
     */
    public static int addNewNode(String szNodeID) {
        // 1. trim 去空格
        String trimmed = trim(szNodeID);

        // 2. 长度校验（替代 strlen + NODEID_LEN）
        if (trimmed.length() != 8) { // 假设 NODEID_LEN = 8
            return -1; // 错误码：长度不符
        }

        // 3. 检查是否已存在（替代 GetNode）
        if (getNode(trimmed) != null) {
            return -2; // 错误码：节点已存在
        }

        // 4. 模拟 calloc 分配节点（直接 new 结构体）
        PKeyEntry newNode = new PKeyEntry();
        newNode.NodeID = trimmed;

        // 5. 替代 AddNode2Mem：插入内存数组（线程安全）
        synchronized (mKeyInfo.lock) { // 替代 pthread_mutex
            int insertPos = 0;
            // 找到插入位置（保持数组有序）
            for (; insertPos < mKeyInfo.nKeyArray.size(); insertPos++) {
                PKeyEntry existNode = mKeyInfo.nKeyArray.get(insertPos);
                if (trimmed.compareTo(existNode.NodeID) < 0) {
                    break;
                }
            }

            // 替代 memmove：Java List 自动处理数组扩容
            mKeyInfo.nKeyArray.add(insertPos, newNode);
            mKeyInfo.nKeyAmount++;
        }

        return 0; // 成功
    }
}
